#pragma once
#include<iostream>
#include<vector>
#include "Sem.hpp"
#include "Mutex.hpp"

using namespace SemModel;
using namespace MutexModel;

template<class T>
class RingQueue{
    public:
    RingQueue(int cap = 5)
        :_cap(cap),_rq(cap),p_step(0),c_step(0),_csem(0),_psem(cap)
    {}
    void Equeue(const T &in){
        _psem.P();
        Guard lockguard(&_pmutex);
        _rq[p_step] = in;
        ++p_step;
        p_step%=_cap;
        _csem.V();
    }
    void Pop(T *out){
        _csem.P();
        Guard lockguard(&_cmutex);
        *out = _rq[c_step];
        c_step++;
        c_step%=_cap;
        _psem.V();
    }
    ~RingQueue(){}

    private:
    std::vector<T> _rq;
    int _cap;
    Mutex _pmutex;
    int p_step;
    Mutex _cmutex;
    int c_step;
    Sem _csem;
    Sem _psem;

};



